package com.ljdemo.lrecorder.model;

import android.media.MediaRecorder;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.text.format.DateFormat;
import android.util.Log;

import androidx.annotation.NonNull;

import java.io.File;
import java.io.IOException;
import java.util.Calendar;
import java.util.Locale;

/**
 * 录音模块，需要自己申请录音权限
 * <br/>
 * 修改日期 : 2023/5/26
 * */
public class AudioRecordMod {

    private static final String Tag="录音模块";

    private MediaRecorder mediaRecorder;//录制对象
    boolean isRecording=false;//录音状态
    private String fileName;//录音文件名称
    private String filePath;//录音文件路径
    private String fileFullName;//文件全名
    private Thread timeThread;//记录录音时长线程
    int timeCount=0;//录音时长计数
    private TimeListener timeListener;//计时监听器（回调函数对象）

    // 用于和计时线程通信的handler，如果不使用handler，activity就不能进行ui操作，因为android不允许子线程直接操作ui
    private Handler handler=new Handler(Looper.myLooper(), new Handler.Callback() {
        @Override
        public boolean handleMessage(@NonNull Message msg) {
            //调用回调函数，通知时间改变
            timeListener.timeChange(timeCount);
            return false;
        }
    });

    // 用于handler发送消息的常量（更新时间）
    private static final int UPDATE_TIME=1;

    /**
     * @param filePath 文件存储路径
     * */
    public AudioRecordMod(String filePath){
        init(filePath);
    }

    /**
     * 默认为公有存储目录 Music
     * */
    public AudioRecordMod(){
        //获取公有存储目录Music
        String path= Environment
                .getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC)
                .toString()+File.separator;
        init(path);
    }

    /**
     * 此类构造器
     * @param filePath 文件存储路径
     * */
    public static AudioRecordMod constructor(String filePath){
        AudioRecordMod audioRecordMod=new AudioRecordMod(filePath);
        return audioRecordMod;
    }

    /**
     * 默认为公有存储目录 Music
     * */
    public static AudioRecordMod constructor(){
        AudioRecordMod audioRecordMod=new AudioRecordMod();
        return audioRecordMod;
    }

    private void init(String filePath){
        //判断最后一个字符是否是 / (文件路径链接符)，不是就加上
        String separator=filePath.substring(filePath.length()-1).trim();
        if (!separator.equals(File.separator)){
            filePath+=File.separator;
        }
        this.filePath=filePath;
    }

    public void setTimeListener(TimeListener timeListener){
        this.timeListener=timeListener;
    }

    /**
     * @param fileName 文件名加后缀
     * */
    public void setFileName(String fileName){
        this.fileName=fileName;
    }

    public void start(){
        if (mediaRecorder==null){
            mediaRecorder=new MediaRecorder();
        }
        this.isRecording=true;
        if (timeListener!=null){
            //开始计时
            countTime();
        }

        // 文件名处理
        if (this.fileName==null||this.fileName.equals("")){
            // 文件名为空设置为 ljdemo当前时间.m4a
            this.fileName="ljdemo"+ DateFormat.format("yyyyMMddHHmmss",
                    Calendar.getInstance(Locale.CHINA))+".m4a";
        }
        this.fileFullName=filePath+fileName;

        // 设置麦克风
        mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        /* 设置输出文件格式：THREE_GPP/MPEG-4/RAW_AMR/Default THREE_GPP(3gp格式，
         * H263视频/ARM音频编码、MPEG-4、RAW_AMR（支持音频且音频编码要求为AMR_NB） */
        mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
        /* 设置音频文件的编码：AAC/AMR_NB/AMR_MB/Default 声音的（波形）的采样 */
        mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);

        // 设置输出文件
        mediaRecorder.setOutputFile(this.fileFullName);
        // 准备
        try {
            mediaRecorder.prepare();
        } catch (IOException e) {
            Log.e(Tag,"mediaRecorder准备时出错："+e.getMessage());
            throw new RuntimeException(e);
        }
        // 开始
        mediaRecorder.start();
    }

    public void stop(){
        try {
            // 停止录制
            mediaRecorder.stop();
            // 释放资源
            mediaRecorder.release();
            mediaRecorder=null;
            fileFullName="";
            fileName="";
            this.isRecording=false;
        }catch (RuntimeException e){
            Log.e(Tag,"停止录音时出错："+e.getMessage());
            e.printStackTrace();
            // 重置mediaRecorder
            mediaRecorder.reset();
            mediaRecorder.release();
            mediaRecorder=null;
            this.isRecording=false;

            // 创建文件夹并删除
            File file=new File(fileFullName);
            if (file.exists()){
                file.delete();
            }
            fileFullName="";
            fileName="";
        }
    }

    private void countTime(){

        timeThread=new Thread(new Runnable() {
            @Override
            public void run() {
                Log.d(Tag,"录音开始计时");
                timeCount=0;
                handler.sendEmptyMessage(UPDATE_TIME);
                while (isRecording){
                    timeCount++;
                    handler.sendEmptyMessage(UPDATE_TIME);
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        Log.e(Tag,"计时线程休眠时出错："+e.getMessage());
                        throw new RuntimeException(e);
                    }
                }
                Log.d(Tag,"录音计时结束");
            }
        });
        timeThread.start();
    }

    public interface TimeListener{
        /**
         * @param time 录音时间，单位为秒
         * */
        void timeChange(int time);
    }

}